﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace BasecampRestAPI
{
	/*
		<todo-list>
		  <id type="integer">#{id}</id>
		  <name>#{name}</name>
		  <description>#{description}</description>
		  <project-id type="integer">#{project_id}</project-id>
		  <milestone-id type="integer">#{milestone_id}</milestone-id>
		  <position type="integer">#{position}</position>

		  <!-- if user can see private lists -->
		  <private type="boolean">#{private}</private>

		  <!-- if the account supports time tracking -->
		  <tracked type="boolean">#{tracked}</tracked>

		  <!-- if todo-items are included in the response -->
		  <todo-items type="array">
			<todo-item>
			  ...
			</todo-item>
			<todo-item>
			  ...
			</todo-item>
			...
		  </todo-items>
		</todo-list>
	 */

	public class ToDoList : IToDoList
	{
		public static ToDoList GetInstance(IBaseCamp baseCamp, XmlNode node)
		{
			return new ToDoList(baseCamp, baseCamp.Service, node);
		}
		private ToDoList(IBaseCamp baseCamp, IRestWebService service, XmlNode node)
		{
			_camp = baseCamp;
			_service = service;
			Id = XmlHelpers.ParseInteger(node, "id");
			Name = XmlHelpers.ChildNodeText(node, "name");
			Description = XmlHelpers.ChildNodeText(node, "description");
			_projectId = XmlHelpers.ParseInteger(node, "project-id");
			_milestoneId = XmlHelpers.ParseInteger(node, "milestone-id");
			Position = XmlHelpers.ParseInteger(node, "position");
			Private = XmlHelpers.ParseBool(node, "private");
			Tracked = XmlHelpers.ParseBool(node, "tracked");
		}
		private readonly IBaseCamp _camp;

		#region Implementation of IToDoList
		public int Id { get; private set; }
		public string Name { get; set; }
		public string Description { get; set; }
		private IProject _project;
		private readonly int _projectId;
		private readonly int _milestoneId;

		public IProject Project
		{
			get
			{
				if (_project == null)
				{
					_project = _camp.GetProjectById(_projectId);
				}
				return _project;
			}
		}

		private IMilestone _milestone;
		private readonly IRestWebService _service;

		public IMilestone Milestone
		{
			get
			{
				if (_milestone == null && _milestoneId != -1)
				{
					_milestone = Project.GetMilestoneById(_milestoneId);
				}
				return _milestone;
			}
			set
			{
				_milestone = value;
			}
		}

		public int Position { get; private set; }
		public bool Private { get; set; }
		public bool Tracked { get; set; }
		public IToDoListItem[] Items
		{
			get
			{
				List<IToDoListItem> items = new List<IToDoListItem>();
				foreach (XmlNode node in _service.GetRequestResponseElement(string.Format("/todo_lists/{0}/todo_items.xml", Id)))
				{
					items.Add(ToDoListItem.GetInstance(_camp, node));
				}
				return items.ToArray();
			}
		}

		public IToDoListItem CreateItem(string content, IPerson responsibleParty, bool notify)
		{
			string requestPath = string.Format("/todo_lists/{0}/todo_items.xml", Id);
			string data;
			if (responsibleParty != null)
			{
				data = string.Format(Properties.Resources.CreateToDoListItemWithResponsiblePartyRequest,
				    XmlHelpers.EscapeXml(content), responsibleParty.Id, notify.ToString().ToLower());
			}
			else
			{
				data = string.Format(Properties.Resources.CreateToDoListItemRequest,
					XmlHelpers.EscapeXml(content));
			}
			string location = _service.PostRequestGetLocation(requestPath, data);
			return ToDoListItem.GetInstance(_camp, _service.GetRequestResponseElement(location));
		}

		public void Delete()
		{
			_service.DeleteRequest(PathForId(Id));
		}

		#endregion

		public static string PathForId(int id)
		{
			return string.Format("todo_lists/{0}.xml", id);
		}
	}
}
